package com.example;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * JVM UseAdaptiveSizePolicy问题演示程序
 * 
 * 模拟生产环境中由于UseAdaptiveSizePolicy动态调整Survivor区大小，
 * 导致对象直接进入老年代，引发频繁Full GC的问题
 */
public class JvmAdaptiveSizeDemo {

    // 存储短生命周期对象的集合
    private static List<Object> shortLivedObjects = new ArrayList<>();
    
    // 存储长生命周期对象的集合
    private static List<Object> longLivedObjects = new ArrayList<>();
    
    // 随机数生成器
    private static Random random = new Random();
    
    // 记录上次打印内存信息的时间
    private static long lastMemoryPrintTime = 0;
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("JVM Adaptive Size Policy 问题演示程序启动");
        System.out.println("JVM 参数: -Xms1536m -Xmx1536m -Xmn512m -XX:MetaspaceSize=512m");
        System.out.println("默认启用 UseAdaptiveSizePolicy");
        System.out.println("==========================================");
        
        // 初始化一些长生命周期对象
        initializeLongLivedObjects();
        
        // 开始模拟业务处理
        simulateBusinessProcessing();
    }
    
    /**
     * 初始化长生命周期对象
     */
    private static void initializeLongLivedObjects() {
        System.out.println("初始化长生命周期对象...");
        for (int i = 0; i < 1000; i++) {
            longLivedObjects.add(new byte[1024]); // 1KB对象
        }
        System.out.println("长生命周期对象初始化完成，数量: " + longLivedObjects.size());
    }
    
    /**
     * 模拟业务处理过程
     * 不断创建短生命周期对象，模拟高并发场景下的内存分配
     */
    private static void simulateBusinessProcessing() throws InterruptedException {
        System.out.println("开始模拟业务处理...");
        int cycleCount = 0;
        
        while (true) {
            // 每个周期创建大量短生命周期对象
            createShortLivedObjects();
            
            // 定期清理部分短生命周期对象，模拟正常垃圾回收
            if (cycleCount % 10 == 0) {
                cleanupSomeShortLivedObjects();
            }
            
            // 添加少量新的长生命周期对象
            if (cycleCount % 50 == 0) {
                addSomeLongLivedObjects();
            }
            
            cycleCount++;
            
            // 控制执行速度，避免CPU占用过高
            Thread.sleep(50);
            
            // 每100个周期输出一次状态
            if (cycleCount % 100 == 0) {
                System.out.println("已执行周期数: " + cycleCount + 
                    ", 当前短生命周期对象数: " + shortLivedObjects.size() +
                    ", 当前长生命周期对象数: " + longLivedObjects.size());
                
                // 每5秒打印一次内存使用情况
                long currentTime = System.currentTimeMillis();
                if (currentTime - lastMemoryPrintTime > 5000) {
                    MemoryMonitor.printMemoryUsage();
                    lastMemoryPrintTime = currentTime;
                }
            }
        }
    }
    
    /**
     * 创建大量短生命周期对象
     * 模拟高并发场景下的对象创建
     */
    private static void createShortLivedObjects() {
        // 每次创建不同数量的对象，模拟实际业务波动
        int objectCount = 5000 + random.nextInt(5000);
        
        for (int i = 0; i < objectCount; i++) {
            // 创建大小不同的对象，模拟真实应用中的对象大小差异
            int size = 64 + random.nextInt(1024); // 64B 到 1KB
            shortLivedObjects.add(new byte[size]);
        }
    }
    
    /**
     * 清理部分短生命周期对象
     * 模拟正常的垃圾回收过程
     */
    private static void cleanupSomeShortLivedObjects() {
        // 清理50%-80%的短生命周期对象
        int cleanCount = (int) (shortLivedObjects.size() * (0.5 + random.nextDouble() * 0.3));
        
        // 保留最近添加的对象（模拟LRU）
        if (cleanCount < shortLivedObjects.size()) {
            shortLivedObjects = new ArrayList<>(shortLivedObjects.subList(
                shortLivedObjects.size() - cleanCount, shortLivedObjects.size()));
        } else {
            shortLivedObjects.clear();
        }
    }
    
    /**
     * 添加少量长生命周期对象
     * 模拟应用中持续增长的数据
     */
    private static void addSomeLongLivedObjects() {
        // 每次添加10-50个长生命周期对象
        int objectCount = 10 + random.nextInt(40);
        
        for (int i = 0; i < objectCount; i++) {
            longLivedObjects.add(new byte[256]); // 256B对象
        }
    }
}